#include "QuadTreeVector.h"

QuadTreeVector::QuadTreeVector():QuadTree() {
	arbol.push_back(VACIO);
	nodoactual = 0;
	lleno = false;
	ultimapos = 0;
	cursor = 0;
	anterior = 0;
}

QuadTreeVector::~QuadTreeVector(){
	arbol.clear();
	arbol.~vector();
}

bool QuadTreeVector::hayLugar(){
	return !lleno;
}

int QuadTreeVector::getPos(int pos){
	int aux;
	aux = pos%4;
	if (aux == 0)
		return 3;
	else
		return (aux-1);
}

int QuadTreeVector::buscar(int pos, int buscado){
	int maxmenor = 0,limite = pos+4;
	while ((arbol[pos] <= buscado) && (pos < limite) ){
		if (arbol[pos] > 0)
			maxmenor = pos;
		pos++;
	}
	return maxmenor;
}


int QuadTreeVector::getPadre(int buscado){
	int cursor = 0;
	if ((arbol[0] == buscado) || (buscado == 0))//el padre es la raiz
		return 0;
	else{
		int primero = buscado - getPos(buscado);
		cursor = buscar(1,primero);
		while (arbol[cursor] != primero){
			cursor = buscar(arbol[cursor],primero);//cursor se va por la rama q tiene q ir
		}
		return cursor;
	}
}

int QuadTreeVector::irSiguiente(int actual){
	int padre = getPadre(actual);
	if (padre == 0)
		return ERR;
	if (getPos(padre) == 3)
		return irSiguiente(padre);
	else
		return padre+1;
}

bool QuadTreeVector::agregarDato(){
	if(!lleno){
		for (int i=0; i<4; i++)
			arbol.push_back(VACIO);
		arbol[nodoactual] = (ultimapos + 1);
		nodoactual = ultimapos + 1;
		ultimapos += 4;
		return true;
	}
	return false;
}

bool QuadTreeVector::agregarDatoHoja(int dato){
	if(!lleno){
		arbol[nodoactual]=(dato*-1);
		if (nodoactual == 0)//caso de agregar una hoja en la raiz
			lleno = true;
		else{
			if (getPos(nodoactual)<3)
				nodoactual++;
			else{
				nodoactual = irSiguiente(nodoactual);//va al siguiente del padre si es posible
				if (nodoactual == ERR)//volvio al padre
					lleno = true;
			}
		}
		return true;
	}
	else
		return false;
}

void QuadTreeVector::irRaiz(){
	anterior = cursor;
	cursor = 0;
}

bool QuadTreeVector::esHoja(){
	return (arbol[cursor] <= 0); //No se puede recorrer un arbol q no este completo
}

bool QuadTreeVector::avanzar(int posicion){
	if (hayLugar() || esHoja() || posicion < 0 || posicion >3 )
		return false;
	else{
		anterior = cursor;
		cursor = arbol[cursor]+posicion;
		return true;
	}
}

void QuadTreeVector::retroceder(){
	if (getPos(cursor) == 3){
		cursor = anterior;
		anterior = getPadre(anterior);
	}
	else
		cursor = anterior;
}

long QuadTreeVector::getDato(){
		return (arbol[cursor]*-1);
}

void QuadTreeVector::mostrar(){
	for (int i=0;i<(int)arbol.size();i++)
				cout<<arbol[i]<<" ";
		cout<<endl;
}

void QuadTreeVector::guardar(ofstream & salida) {
	int tamanio = arbol.size();
	salida.write((char *)&VECTOR,sizeof(int));
	salida.write((char *)&tamanio,sizeof(int));
	for (int i = 0; i < tamanio; i++)
		salida.write((char *)&arbol[i],sizeof(int));
}

void QuadTreeVector::recuperar(ifstream & entrada) {
	int tamanio = 0;
	int aux = 0;
	arbol.clear();
	entrada.read((char *)&tamanio,sizeof(int));
	for (int i = 0; i<tamanio; i++){
		entrada.read((char *)&aux,sizeof(int));
		arbol.push_back(aux);
	}
	lleno = true;

}
